package com.example.fashion.android.MultiMedia.activity;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

import com.example.fashion.android.MultiMedia.view.ICameraView;
import com.example.fashion.android.R;
import com.example.fashion.android.base.BaseActivity.BaseActivity;
import com.example.fashion.android.util.FileUtil.FileUtil;
import com.example.fashion.android.util.ImageUtil.ImageUtil;
import com.example.fashion.android.util.LogUtil.L;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by fashion on 2017/10/10.
 */

public class CameraActivity extends BaseActivity implements ICameraView, View.OnClickListener {
    private SurfaceView mSurfaceView;
    private Camera mCamera;
    private Camera.Parameters parameters;
    private boolean preview = false;
    private Point screenResolution;
    private static Point cameraResolution;
    private int mCameraPosition = Camera.CameraInfo.CAMERA_FACING_BACK;//默认后置摄像头
    private SurfaceHolder holder;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
    }

    @Override
    public void initView() {
        //隐藏标题栏
        hideSystemTitleBar();

        //获得控件
        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);

        //添加监听事件
        findViewById(R.id.take_photo_btn).setOnClickListener(this);
        findViewById(R.id.btn_change).setOnClickListener(this);
        mSurfaceView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mCamera.autoFocus(null);
                return false;
            }
        });

    }


    @Override
    public void initData() {
//        if (!checkCameraHardware(this)) {
//            mToastUtil.showToast("相机不支持");
//        } else {
        openCamera();
//        }
    }



    // 聚焦回调
    private Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            if (success) {
                /* 实现相机拍照的主要方法,传入三个回调方法
                1.shutter是快门按下时的回调
                2.raw是获取拍照原始数据的回调
                3.jpeg是获取经过压缩成jpg格式的图像数据的回调。
                 */
                mCamera.takePicture(null, null, mPictureCallback);
            }
        }
    };


    /**
     * SufaceView生命周期的监听方法
     */
    private final class SufaceListener implements SurfaceHolder.Callback {
        //在surface创建后立即被调用
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
            try {
                //打开相机
                getCameraInstance();
                //绑定绘制预览图像的surface
                mCamera.setPreviewDisplay(holder);// 通过SurfaceView显示取景画面
                //初始化相机
                initCamera();
                preview = true;
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        //在surface发生format或size变化时调用
        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
            //实现自动对焦
            mCamera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success) {
                        initCamera();
                        camera.cancelAutoFocus();
                    }
                }

            });
        }

        //在surface销毁之前被调用
        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
            if (mCamera != null) {
                if (preview) {
                    mCamera.stopPreview();
                }
                mCamera.release();
                mCamera = null;
            }
        }
    }

    // 拍照回调
    private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(final byte[] data, final Camera camera) {
            //关闭预览
            camera.stopPreview();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    //获得图片
                    Bitmap cameraBitmap1 = ImageUtil.getBitmap(data, 700, 1000);
                    Bitmap cameraBitmap2;
                    //旋转图片(如果是前置摄像头的话, 旋转应该是 -90度)
                    if (mCameraPosition == Camera.CameraInfo.CAMERA_FACING_BACK) {
                        cameraBitmap2 = ImageUtil.rotateBitmapByDegree(cameraBitmap1, 90);
                    } else {
                        cameraBitmap2 = ImageUtil.rotateBitmapByDegree(cameraBitmap1, -90);
                    }
                    //剪切图片
                    Bitmap cameraBitmap3 = ImageUtil.getCutBitmap(cameraBitmap2, 1000, 667);
                    //插入到相册数据库
                    String path;
                    try {
                        //插入数据库
                        String url = insertImage(CameraActivity.this.getContentResolver(), cameraBitmap3, "image", "CameraActivity");
                        //获得图片的真实路径
                        path = getRealFilePath(CameraActivity.this, Uri.parse(url));
                    } catch (Exception e) {
                        String photoDir = FileUtil.getImageDownloadDir(getApplicationContext());
                        String fileName = "album_" + new Random().nextInt(1000) + "-" + System.currentTimeMillis() + ".jpg";
                        path = new File(photoDir, fileName).getPath();
                        FileUtil.writeBitmapToSD(path, cameraBitmap3, Bitmap.CompressFormat.JPEG, 100);
                        e.printStackTrace();
                    }
                    L.e("chen","保存图片的路径："+path);
                    if (cameraBitmap1 != null) {
                        cameraBitmap1.recycle();
                    }
                    if (cameraBitmap2 != null) {
                        cameraBitmap2.recycle();
                    }
                    if (cameraBitmap3 != null) {
                        cameraBitmap3.recycle();
                    }
                    camera.startPreview();
                }
            }).start();
        }
    };


    /**
     * 相机参数的初始化设置
     */
    private void initCamera() {
        parameters = mCamera.getParameters();
        parameters.setPictureFormat(PixelFormat.JPEG);
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//1连续对焦
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
        parameters.setJpegQuality(100); // 设置照片质量
        //获得手机支持的尺寸
        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
        List<Camera.Size> pictureSizes = parameters.getSupportedPictureSizes();
        //获得屏幕大小
        WindowManager manager = (WindowManager) this.getBaseContext()
                .getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        DisplayMetrics metrics = new DisplayMetrics();
        display.getRealMetrics(metrics);
        screenResolution = new Point(metrics.widthPixels, metrics.heightPixels);
        // preview size is always something like 480*320, other 320*480
        Point screenResolutionForCamera = new Point();
        screenResolutionForCamera.x = screenResolution.x;
        screenResolutionForCamera.y = screenResolution.y;
        // preview size is always something like 480*320, other 320*480
        if (screenResolution.x < screenResolution.y) {
            screenResolutionForCamera.x = screenResolution.y;
            screenResolutionForCamera.y = screenResolution.x;
        }

        //获得最佳的图片大小
        cameraResolution = findBestPreviewSizeValue(previewSizes, screenResolution);
        Camera.Size previewSize = getBestSize(1.3, previewSizes, screenResolutionForCamera.y, screenResolutionForCamera.x);
        Camera.Size pictureSize = getBestSize(1.3, pictureSizes);
        if (previewSize == null || pictureSize == null) {
            parameters.setPreviewSize(cameraResolution.y, cameraResolution.x);
            parameters.setPictureSize(0, 0);
        } else {
            parameters.setPreviewSize(previewSize.width, previewSize.height);
            parameters.setPictureSize(pictureSize.width, pictureSize.height);
        }

        //设置surfaceView的大小（同预览大小相同）
        ViewGroup.LayoutParams p = mSurfaceView.getLayoutParams();
        p.width = previewSize.height;
        p.height = previewSize.width;
        mSurfaceView.setLayoutParams(p);

        //设置显示方向（后置摄像头旋转90度，前置摄像头需旋转180度）
        if (mCameraPosition == Camera.CameraInfo.CAMERA_FACING_BACK) {
            mCamera.setDisplayOrientation(90);
        } else {
            mCamera.setDisplayOrientation(180);
        }
//        setCameraDisplayOrientation(this, mCameraPosition, mCamera);
        mCamera.setParameters(parameters);
        try {
            mCamera.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
        mCamera.cancelAutoFocus();
    }

    /**
     * 找到最佳预览大小值
     *
     * @param list
     * @param screenResolution
     * @return
     */
    private Point findBestPreviewSizeValue(
            List<Camera.Size> list, Point screenResolution) {
        int bestX = 0;
        int bestY = 0;
        int diff = Integer.MAX_VALUE;
        for (Camera.Size previewSize : list) {
            int newX = previewSize.width;
            int newY = previewSize.height;

            int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y);
            if (newDiff == 0) {
                bestX = newX;
                bestY = newY;
                break;
            } else if (newDiff < diff) {
                bestX = newX;
                bestY = newY;
                diff = newDiff;
            }
        }
        if (bestX > 0 && bestY > 0) {
            return new Point(bestX, bestY);
        }
        return null;
    }

    /**
     * 获得最佳的图片大小
     *
     * @param sizeScale
     * @param SizeList
     * @param width
     * @param height
     * @return
     */
    public Camera.Size getBestSize(double sizeScale, List<Camera.Size> SizeList, int width, int height) {

        Camera.Size bigSize = null;
        double l = sizeScale - 0.1;
        double u = sizeScale + 0.1;

        List<Camera.Size> newPreviewSizes = new ArrayList<>();
        for (Camera.Size previewSize : SizeList) {
            double w = (double) previewSize.width;
            double h = (double) previewSize.height;
            if (l < w / h && w / h < u && (w + h) <= (width + height)) {
                newPreviewSizes.add(previewSize);
            }
        }

        if (newPreviewSizes.size() > 0) {
            for (Camera.Size size : newPreviewSizes) {
                if (bigSize == null) {
                    bigSize = size;
                    continue;
                } else {
                    if ((size.width + size.height) > (bigSize.width + bigSize.height)) {
                        bigSize = size;
                    }
                }
            }
        }
        return bigSize;

    }

    /**
     * 获得最佳的图片大小
     *
     * @param sizeScale
     * @param SizeList
     * @return
     */
    public Camera.Size getBestSize(double sizeScale, List<Camera.Size> SizeList) {

        Camera.Size bigSize = null;
        double l = sizeScale - 0.1;
        double u = sizeScale + 0.1;

        List<Camera.Size> newPreviewSizes = new ArrayList<>();
        for (Camera.Size previewSize : SizeList) {
            double w = (double) previewSize.width;
            double h = (double) previewSize.height;
            if (l < w / h && w / h < u) {
                newPreviewSizes.add(previewSize);
            }
        }

        if (newPreviewSizes.size() > 0) {
            for (Camera.Size size : newPreviewSizes) {
                if (bigSize == null) {
                    bigSize = size;
                    continue;
                } else {
                    if ((size.width + size.height) > (bigSize.width + bigSize.height)) {
                        bigSize = size;
                    }
                }
            }
        }
        return bigSize;

    }

    /**
     * 插入图片到数据库
     *
     * @param cr
     * @param source
     * @param title
     * @param description
     * @return
     */
    public final String insertImage(ContentResolver cr, Bitmap source,
                                    String title, String description) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, title);
        values.put(MediaStore.Images.Media.DESCRIPTION, description);
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");

        Uri url = null;
        String stringUrl = null;

        try {
            //插入到数据库
            url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

            if (source != null) {
                OutputStream imageOut = cr.openOutputStream(url);
                try {
                    //图片压缩
                    source.compress(Bitmap.CompressFormat.JPEG, 70, imageOut);
                } finally {
                    imageOut.close();
                }

            } else {
                cr.delete(url, null, null);
                url = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            if (url != null) {
                cr.delete(url, null, null);
                url = null;
            }
        }

        if (url != null) {
            stringUrl = url.toString();
        }

        return stringUrl;
    }

    /**
     * 获得图片真实路径
     *
     * @param context
     * @param uri
     * @return
     */
    public String getRealFilePath(final Context context, final Uri uri) {
        if (null == uri) return null;
        final String scheme = uri.getScheme();
        String data = null;
        if (scheme == null)
            data = uri.getPath();
        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            data = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            Cursor cursor = context.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                    if (index > -1) {
                        data = cursor.getString(index);
                    }
                }
                cursor.close();
            }
        }
        return data;
    }

    /**
     * 获取相机实例
     * @return
     */
    public Camera getCameraInstance() {
        try {
            mCamera = Camera.open(mCameraPosition);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return mCamera;
    }

    /**
     * 开始预览相机
     */
    public void openCamera() {
        //        //获得surface句柄
        holder = mSurfaceView.getHolder();
//        //添加回调监听
        holder.addCallback(new SufaceListener());
//        /* 下面设置Surface不维护自己的缓冲区，而是等待屏幕的渲染引擎将内容推送到用户面前 */
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        holder.setKeepScreenOn(true);// 屏幕常亮
        holder.setFixedSize(300, 300); // 设置分辨率
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.take_photo_btn:       //拍照按钮
                mCamera.autoFocus(mAutoFocusCallback);
                break;
            case R.id.btn_change:       //切换摄像头
                switchCamera();
                break;
        }
    }

    /**
     * 释放相机
     */
    public void releaseCamera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * 切换摄像头
     */
    public void switchCamera() {
        //切换前后摄像头
        int cameraCount;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数

        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
            if (mCameraPosition == Camera.CameraInfo.CAMERA_FACING_BACK) {
                //现在是后置，变更为前置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位，CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    mCamera.stopPreview();//停掉原来摄像头的预览
                    mCamera.release();//释放资源
                    mCamera = null;//取消原来摄像头
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(holder);//通过surfaceview显示取景画面
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    mCamera.setDisplayOrientation(90);
                    mCamera.startPreview();//开始预览
                    mCameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;
                    break;
                }
            } else {
                //现在是前置， 变更为后置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位，CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    mCamera.stopPreview();//停掉原来摄像头的预览
                    mCamera.release();//释放资源
                    mCamera = null;//取消原来摄像头
                    mCamera = Camera.open(i);//打开当前选中的摄像头
                    try {
                        mCamera.setPreviewDisplay(holder);//通过surfaceview显示取景画面
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    mCamera.setDisplayOrientation(90);
                    mCamera.startPreview();//开始预览
                    mCameraPosition = Camera.CameraInfo.CAMERA_FACING_BACK;
                    break;
                }
            }
        }
    }


    @Override
    protected void clear() {

    }
}
